
package com.doc2video.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.doc2video.common.Result;
import com.doc2video.dto.UserLoginDTO;
import com.doc2video.dto.UserRegisterDTO;
import com.doc2video.entity.User;
import com.doc2video.mapper.UserMapper;
import com.doc2video.service.UserService;
import com.doc2video.utils.JwtUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * 用户Service实现类
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    @Transactional
    public Result<String> register(UserRegisterDTO registerDTO) {
        // 验证密码是否一致
        if (!registerDTO.getPassword().equals(registerDTO.getConfirmPassword())) {
            return Result.error("两次输入的密码不一致");
        }

        // 检查用户名是否已存在
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, registerDTO.getUsername());
        if (userMapper.selectCount(wrapper) > 0) {
            return Result.error("用户名已存在");
        }

        // 检查邮箱是否已存在
        if (registerDTO.getEmail() != null && !registerDTO.getEmail().isEmpty()) {
            wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(User::getEmail, registerDTO.getEmail());
            if (userMapper.selectCount(wrapper) > 0) {
                return Result.error("邮箱已被注册");
            }
        }

        // 检查手机号是否已存在
        if (registerDTO.getPhone() != null && !registerDTO.getPhone().isEmpty()) {
            wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(User::getPhone, registerDTO.getPhone());
            if (userMapper.selectCount(wrapper) > 0) {
                return Result.error("手机号已被注册");
            }
        }

        // 创建用户
        User user = new User();
        BeanUtils.copyProperties(registerDTO, user);
        user.setPassword(passwordEncoder.encode(registerDTO.getPassword()));
        user.setNickname(registerDTO.getNickname() != null ? registerDTO.getNickname() : registerDTO.getUsername());
        user.setUserType(0); // 普通用户
        user.setStatus(0); // 正常状态
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());

        userMapper.insert(user);

        return Result.success("注册成功");
    }

    @Override
    public Result<String> login(UserLoginDTO loginDTO, HttpServletRequest request) {
        // 查询用户
        User user = userMapper.selectByUsername(loginDTO.getUsername());
        if (user == null) {
            return Result.error("用户名或密码错误");
        }

        // 验证密码
        if (!passwordEncoder.matches(loginDTO.getPassword(), user.getPassword())) {
            return Result.error("用户名或密码错误");
        }

        // 检查用户状态
        if (user.getStatus() == 1) {
            return Result.error("账号已被禁用，请联系管理员");
        }

        // 生成JWT token
        String token = jwtUtils.generateToken(user.getId().toString());

        // 更新最后登录时间
        user.setLastLoginTime(LocalDateTime.now());
        userMapper.updateById(user);

        // 将用户信息存入Redis
        String userKey = "user:" + user.getId();
        redisTemplate.opsForValue().set(userKey, user, 24, TimeUnit.HOURS);

        return Result.success(token);
    }

    @Override
    public Result<String> logout(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
            String userId = jwtUtils.getUserIdFromToken(token);
            if (userId != null) {
                // 从Redis中删除用户信息
                String userKey = "user:" + userId;
                redisTemplate.delete(userKey);
            }
        }
        return Result.success("退出成功");
    }

    @Override
    public Result<User> getCurrentUser(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        if (token == null || !token.startsWith("Bearer ")) {
            return Result.error("未登录或token无效");
        }

        token = token.substring(7);
        String userId = jwtUtils.getUserIdFromToken(token);
        if (userId == null) {
            return Result.error("token无效");
        }

        // 从Redis中获取用户信息
        String userKey = "user:" + userId;
        User user = (User) redisTemplate.opsForValue().get(userKey);
        
        if (user == null) {
            // 如果Redis中没有，从数据库查询
            user = userMapper.selectById(Long.parseLong(userId));
            if (user != null) {
                redisTemplate.opsForValue().set(userKey, user, 24, TimeUnit.HOURS);
            }
        }

        if (user == null) {
            return Result.error("用户不存在");
        }

        return Result.success(user);
    }

    @Override
    @Transactional
    public Result<String> updateUserInfo(User user, HttpServletRequest request) {
        Result<User> currentUserResult = getCurrentUser(request);
        if (!currentUserResult.getCode().equals(200)) {
            return Result.error(currentUserResult.getMessage());
        }

        User currentUser = currentUserResult.getData();
        currentUser.setNickname(user.getNickname());
        currentUser.setEmail(user.getEmail());
        currentUser.setPhone(user.getPhone());
        currentUser.setAvatar(user.getAvatar());
        currentUser.setUpdateTime(LocalDateTime.now());

        userMapper.updateById(currentUser);

        // 更新Redis中的用户信息
        String userKey = "user:" + currentUser.getId();
        redisTemplate.opsForValue().set(userKey, currentUser, 24, TimeUnit.HOURS);

        return Result.success("更新成功");
    }

    @Override
    @Transactional
    public Result<String> changePassword(String oldPassword, String newPassword, HttpServletRequest request) {
        Result<User> currentUserResult = getCurrentUser(request);
        if (!currentUserResult.getCode().equals(200)) {
            return Result.error(currentUserResult.getMessage());
        }

        User currentUser = currentUserResult.getData();

        // 验证旧密码
        if (!passwordEncoder.matches(oldPassword, currentUser.getPassword())) {
            return Result.error("旧密码错误");
        }

        // 更新密码
        currentUser.setPassword(passwordEncoder.encode(newPassword));
        currentUser.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(currentUser);

        // 更新Redis中的用户信息
        String userKey = "user:" + currentUser.getId();
        redisTemplate.opsForValue().set(userKey, currentUser, 24, TimeUnit.HOURS);

        return Result.success("密码修改成功");
    }

    @Override
    public User getByUsername(String username) {
        return userMapper.selectByUsername(username);
    }
}
